(* gui.ml - Main file for GUI management
 * Licence: LGPLv3
 * Authors: Antoine 'Dak' Parenton, FEAR OF THE DAK
 *)

let file_path = ref ""
let file_color = ref ""

(* Main window *)
let window1 =
  ignore (GMain.init ());
  let wnd = GWindow.window
    ~title:"Fear of the Map"
    ~position:`CENTER
    ~width:800
    ~height:600
    ~resizable:false () in
  ignore (wnd#connect#destroy ~callback:GMain.quit);
  wnd

(* Warning dialog when you delete the main window *)
let confirm _ =
  let dialog = GWindow.message_dialog
    ~title:"Fear of the Map"
    ~message:
    "<b><big>Voulez-vous vraiment quitter ?</big></b>\n\n
<u>Attention</u>: toute vos donnees non-sauvegardees seront perdues !"
    ~parent:window1
    ~destroy_with_parent:true
    ~use_markup:true
    ~message_type:`QUESTION
    ~position:`CENTER_ON_PARENT
    ~buttons:GWindow.Buttons.yes_no () in
  let result = dialog#run () = `NO in
  ignore (try (Image_functions.end_heights (Hashtbl.find
					      Image.images
					      !file_color)) with _ -> exit 0);
  ignore (try (Image_functions.remove_tmp
		 (Hashtbl.find Image.images !file_color)) with _ -> exit 0);
  dialog#destroy ();
  result

(* Vertical main box container *)
let vbox1 =
  GPack.vbox
    ~spacing:4
    ~border_width:4
    ~homogeneous:false
    ~packing:window1#add ()
    
(* NOTEBOOK *)
let notebook1 =
  let notebook =
    GPack.notebook
      ~homogeneous_tabs:true
      ~show_border:true
      ~show_tabs:true
      ~border_width:4
      ~width:700
      ~height:550
      ~packing:vbox1#pack ()
  in
  notebook
    
let tab1 =
  GPack.hbox
    ~homogeneous:false
    ~spacing:4
    ~border_width:4
    ~packing:notebook1#add ()

let tab2 =
  GPack.hbox
    ~homogeneous:false
    ~spacing:4
    ~border_width:4
    ~packing:notebook1#add ()

let tab3 =
  GPack.vbox
    ~homogeneous:false
    ~spacing:4
    ~border_width:4
    ~packing:notebook1#add ()

(* Horizontal box for buttons *)
let hbox1 =
  GPack.hbox
    ~spacing:4
    ~border_width:4
    ~homogeneous:false
    ~packing:vbox1#pack ()

(* Print the file chosen in the console *)
let may_print button () =
  Gaux.may print_endline button#filename

let img2 =
  GMisc.image
    ~file:!file_path
    ~packing:tab1#add ()

let img3 =
  GMisc.image
    ~file:!file_path
    ~packing:tab2#add()

let file_ok_sel filew () =
  Image.load filew#filename;
  file_path:= filew#filename;
  file_color:= filew#filename;
  print_endline filew#filename;
  flush stdout

(* FILE CHOOSER BUTTON *)
let file_button =
  let file = GWindow.file_selection
    ~title:"Selection de la map: "
    ~border_width:10
    ~parent:window1
    ~destroy_with_parent:true () in
  let button = GButton.button ~label:"Parcourir" ~stock:`OPEN
    ~packing:hbox1#add () in
  ignore (GMisc.image ~stock:`OPEN ~packing:button#set_image ());
  ignore (button#connect#clicked (fun () -> ignore (file#run ());
    file#misc#hide ()));
  ignore (file#ok_button#connect#clicked (file_ok_sel file));
  button

let pixbuf_ok_sel image width height =
  let pixbuf = GdkPixbuf.from_file_at_size (!file_path)
    ~width:width
    ~height:height
  in
  image#set_pixbuf pixbuf

(* Apply Button*)
let apply_button =
  let button = GButton.button
    ~stock:`APPLY
    ~show:true
    ~packing:hbox1#add () in
  ignore (GMisc.image ~stock:`APPLY ~packing:button#set_image ());
    (*ignore (button#connect#clicked ~callback:(fun () -> !img2#set_file
      (!file_path)));*)
  ignore (button#connect#clicked
	    (fun () -> try (
	      file_path:= !file_color;
	      ignore (if (!file_path = "") then () else
		  begin
		    ignore (Image.load !file_path);
		    Image_functions.image2grey (Hashtbl.find
						  Image.images
						  !file_path);
		    Image_functions.edge_detection (Hashtbl.find
						      Image.images
						      !file_path);
		    Image_functions.iwedges (Hashtbl.find
					       Image.images
					       !file_path);
		    Image_functions.gwedges (Hashtbl.find
					       Image.images
					       !file_path);
		    Image_functions.init_heights (Hashtbl.find
						    Image.images
						    !file_color);
		    ignore (Image_functions.get_next
			      (Hashtbl.find Image.images !file_color))
		  end
	      )
	     ) with _ -> ()
	    ));
  ignore (button#connect#clicked (fun () -> try (pixbuf_ok_sel img2 600
						   500) with _ -> ()));
  ignore (button#connect#clicked
	    (fun () -> try
			 (file_path := !file_color^".0.bmp";
			  (pixbuf_ok_sel img3 600 500)) with _ -> () ));
  button

(* NOTEBOOK1 *)
let buttonVbox1 =
  GPack.vbox
    ~spacing:4
    ~border_width:4
    ~homogeneous:false
    ~packing:tab1#pack ()

let mapButton =
  let button = GButton.button
    ~label:"Carte"
    ~packing:buttonVbox1#add () in
    ignore (button#connect#clicked
	      (fun () -> try (file_path := !file_color;
			      img2#set_file (!file_path);
			      pixbuf_ok_sel img2 600 500) with _ -> ()));
  button

let greyButton =
  let button = GButton.button
    ~label:"Niveaux de gris"
    ~packing:buttonVbox1#add () in
  ignore (button#connect#clicked
	    (fun () -> try (file_path := !file_color^".grey.bmp";
			    img2#set_file (!file_path);
			    pixbuf_ok_sel img2 600 500) with _ -> ()));
  button

let edgesButton =
  let button = GButton.button
    ~label:"Contours\nsur blanc"
    ~packing:buttonVbox1#add () in
  ignore (button#connect#clicked
	    (fun () -> try( file_path := !file_color^".edges.bmp";
			    img2#set_file (!file_path);
			    pixbuf_ok_sel img2 600 500) with _-> ()));
  button

let gwedgesButton =
  let button = GButton.button
    ~label:"Contours\nsur gris"
    ~packing:buttonVbox1#add () in
  ignore (button#connect#clicked
	    (fun () -> try (file_path := !file_color^".gwedges.bmp";
			    img2#set_file (!file_path);
			    pixbuf_ok_sel img2 600 500) with _ -> ()));
  button

let iwedgesButton =
  let button = GButton.button
    ~label:"Contours\nsur couleur"
    ~packing:buttonVbox1#add () in
  ignore (button#connect#clicked
	    (fun () -> try (file_path := !file_color^".iwedges.bmp";
			    img2#set_file (!file_path);
			    pixbuf_ok_sel img2 600 500) with _ -> ()));
  button


(* END OF NOTEBOOK1 *)

(* NOTEBOOK2 *)
let buttonVbox2 =
  GPack.vbox
    ~spacing:4
    ~border_width:4
    ~homogeneous:false
    ~packing:tab2#pack ()

let secondaryBox =
  GPack.vbox
    ~border_width:4
    ~homogeneous:false
    ~packing:buttonVbox2#add ()

let label1 =
  GMisc.label
    ~text:"Hauteur:"
    ~packing:secondaryBox#pack ()

let adjustement =
  GData.adjustment
    ~value:0.
    ~page_size:0.
    ~step_incr:1. ()

let heightSpin1 =
  GEdit.spin_button
    ~adjustment:adjustement
    ~width:105
    ~digits:0
    ~numeric:true
    ~packing:secondaryBox#pack ()

let label1 =
  GMisc.label
    ~text:"Pas:"
    ~packing:secondaryBox#pack ()

let adjustement2 =
  GData.adjustment
    ~value:1.
    ~lower:1.
    ~page_size:0.
    ~step_incr:1. ()

let heightSpin2 =
  GEdit.spin_button
    ~adjustment:adjustement2
    ~width:105
    ~digits:0
    ~numeric:true
    ~packing:secondaryBox#pack ()

let height= ref 0
let step = ref 20

let color1Button =
  let button = GButton.button
    ~label:"  Zone\nsuivante"
    ~packing:buttonVbox2#add () in
  ignore (button#connect#clicked
	    (fun () -> height:= (heightSpin1#value_as_int) ));
  ignore (button#connect#clicked
	    (fun () -> (heightSpin1#set_value 0.)));
  ignore (button#connect#clicked (fun () ->
    if (try (Image_functions.get_next (Hashtbl.find
					 Image.images
					 !file_color)) with _ -> false)
    then
      begin
	file_path :=Image_functions.get_hfile ();
	Image_functions.register_height
	  (Hashtbl.find Image.images
	     !file_color) (!height * 10);
	pixbuf_ok_sel img3 600 500;
      end
  ));
  button

let applyButton =
  let button = GButton.button
    ~label:"Enregistrer\n les valeurs"
    ~packing:buttonVbox2#add () in
  ignore (button#connect#clicked
	    (fun () ->
	      try ((Image_functions.register_height
		      (Hashtbl.find Image.images !file_color)
		      (!height * 10);
		    Image_functions.save_heights
		      (Hashtbl.find Image.images !file_color)))
	      with _ -> ()
	    ));
  ignore (button#connect#clicked
	    (fun () -> step := (heightSpin2#value_as_int)));
  ignore (button#connect#clicked
	    (fun () -> heightSpin2#set_value 0.));
  ignore (button#connect#clicked
	    (fun () ->
	      Parser.gen_obj_ (Hashtbl.find Image.images !file_color)
		!step));
  button

(* END OF NOTEBOOK2 *)

let display3Dbutton =
  let button = GButton.button
    ~label:"Affichage 3D"
    ~packing:tab3#add () in
  ignore (button#connect#clicked (fun () -> Args_manager.fobj !file_color));
  button

(* About button with credits, license, website *)
let about_button =
  let dialog = GWindow.about_dialog
    ~authors:
    ["Tribute: \nFranck \"kushou\" Michea\n<franck.michea AT epita DOT fr>\nRaphaël \"Sharr\" Chardon\n<raphael.chardon AT epita DOT fr>\nNicolas \"Dace\" Brohée\n<nicolas.brohee AT epita DOT fr> \nAntoine \"Dak\" Parenton\n<antoine.parenton AT epita DOT fr>"]
    ~copyright:"Fear of the Map © 2010-2011 Tribute"
    ~license:"LGPLv3"
    ~version:"v0.3"
    ~website:"http://www.fearofthedak.com/fotm/"
    ~website_label:"http://www.fearofthedak.com/fotm/"
    ~position:`CENTER_ON_PARENT
    ~parent:window1
    ~destroy_with_parent:true () in
  let button = GButton.button ~stock:`ABOUT ~packing:hbox1#add
    () in
  ignore (GMisc.image ~stock:`ABOUT ~packing:button#set_image ());
  ignore (button#connect#clicked
	    (fun () -> ignore (dialog#run ());
	      dialog#misc#hide ()));
  button

(* Quit button (without warning) *)
let quit_button =
  let button = GButton.button
    ~stock:`QUIT
    ~packing:hbox1#add () in
  ignore (GMisc.image ~stock:`QUIT ~packing:button#set_image ());
  ignore (button#connect#clicked
	    (fun () ->
	      try (Image_functions.end_heights
		     (Hashtbl.find Image.images !file_color))
	      with _ -> exit 0));
  ignore (button#connect#clicked
	    (fun () -> try (Image_functions.remove_tmp
			      (Hashtbl.find Image.images !file_color))
	      with _ -> exit 0));
  ignore (button#connect#clicked ~callback:GMain.quit);
  button

let main () =
  ignore (window1#event#connect#delete confirm);
  window1#show ();
  GMain.main ()
